﻿#region License
// Copyright (c) 2009 Shun Chi Guo
// E-Mail:shuncy@gmail.com
// Blog:http://shuncy.cnblogs.com
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Text.RegularExpressions;
using System.IO;

namespace shun.PAPLib
{
    public enum SendType
    {
        SI,
        SL
    }

    public abstract class IRequest
    {

        #region 需要实现的方法
        protected abstract void ControlBody(XmlWriter xml);
        protected abstract void ContentBody(XmlWriter xml);
        protected abstract void CapabilitiesBody(XmlWriter xml);

        /// <summary>
        /// 是否处理内容
        /// </summary>
        protected abstract bool ProcContent {get; }
        /// <summary>
        /// 是否处理扩展 属性
        /// </summary>
        protected abstract bool ProcCapabilities { get; }
        #endregion

        #region 公共属性
        static Random rd = new Random();
        static string _id = String.Empty;
        /// <summary>
        /// 消息ID，用于记录发送消息 
        /// </summary>
        public string PushID { get; set; }

        protected static string GetPushID()
        {
            return DateTime.Now.ToString("yyyyMMddmmhhss") + rd.Next(999999).ToString("000000");
        }

        /// <summary>
        /// 分界字符串
        /// </summary>
        public static string Boundary
        {
            get
            {
                if (_id == String.Empty)
                {
                    _id = Guid.NewGuid().ToString().Replace("-", "");
                }
                return _id;
            }
        }
        /// <summary>
        /// 换行符
        /// </summary>
        protected static string NewLine = "\r\n";
        
        /// <summary>
        /// 控制消息头内容
        /// </summary>
        protected static string ControlHead = "--" + Boundary + NewLine + "Content-Type: application/xml" + NewLine + NewLine;
        /// <summary>
        /// 内容消息头内容
        /// </summary>
        protected string ContentHead = "";
        /// <summary>
        /// 终端能力头内容
        /// </summary>
        protected static string CapabilitiesHead = NewLine + "--" + Boundary + NewLine + "Content-Type: application/xml" + NewLine + NewLine;
        /// <summary>
        /// 结束分隔符
        /// </summary>
        protected static string EndBoundary = NewLine + "--" + Boundary + "--";

        #endregion

        #region 公共方法
        /// <summary>
        /// 取得包的字符串信息
        /// </summary>
        /// <returns></returns>
        public string GetString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(ControlHead);
            sb.Append(GetControlXml());

            if (ProcContent)
            {
                sb.Append(ContentHead);
                sb.Append(GetContentXml());
            }

            if (ProcCapabilities)
            {
                sb.Append(CapabilitiesHead);
                sb.Append(GetCapabilitiesXml());
            }
            sb.Append(EndBoundary);
            return sb.ToString();
        }

        /// <summary>
        /// 取得当前包的字节数组，默认UTF-8编码
        /// </summary>
        /// <returns></returns>
        public byte[] GetBytes()
        {
            return GetBytes(Encoding.UTF8);
        }
        /// <summary>
        /// 根据指定的编码取得当前包的字节数据
        /// </summary>
        /// <param name="enc">指定的编码</param>
        /// <returns></returns>
        public byte[] GetBytes(Encoding enc)
        {
            return enc.GetBytes(GetString());
        }

        private XmlWriter CreateXml(string enc, MemoryStream ms)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            if (String.IsNullOrEmpty(enc))
            {
                settings.Encoding = Encoding.UTF8;
            }
            else
            {
                settings.Encoding = Encoding.GetEncoding(enc);
            }
            settings.Indent = false;
            XmlWriter xdc = XmlWriter.Create(ms, settings);
            return xdc;
        }

        /// <summary>
        /// 取得控制部份的Xml字串
        /// </summary>
        /// <returns></returns>
        public string GetControlXml()
        {
            MemoryStream ms = new MemoryStream();
            string rtn = "";
            try
            {
                XmlWriter xml = CreateXml("iso-8859-1", ms);
                xml.WriteStartDocument();
                //添加申明信息
                xml.WriteDocType("pap", "-//WAPFORUM//DTD PAP 1.0//EN", "http://www.wapforum.org/DTD/wml_1.1.xml", null);

                //创建PAP节点
                xml.WriteStartElement("pap");
                //创建内容部份
                ControlBody(xml);
                //结束PAP节点
                xml.WriteEndElement();
                //结束文档
                xml.WriteEndDocument();

                xml.Close();
                rtn = Encoding.UTF8.GetString(ms.ToArray());
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                ms.Close();
                ms.Dispose();
            }
            return rtn;
        }

        /// <summary>
        /// 取得内容部份的XMl字串
        /// </summary>
        /// <param name="st"></param>
        /// <returns></returns>
        protected string GetContentXml()
        {
            MemoryStream ms = new MemoryStream();
            string rtn = "";
            bool bUse = false;
            try
            {
                XmlWriter xml = CreateXml("", ms);
                //创建内容部份
                ContentBody(xml);
                //结束文档
                xml.WriteEndDocument();

                xml.Close();
                rtn = Encoding.UTF8.GetString(ms.ToArray());
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                ms.Close();
                ms.Dispose();
            }
            return rtn;
        }

        protected static string GetCapabilitiesXml()
        {
            throw new Exception("暂未实现");
        }
        #endregion
    }
}
